package com.ruyi.afterdemo.comm;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.domain.Sort.Order;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.domain.Specifications;
import org.springframework.util.StringUtils;

import java.io.Serializable;
import java.util.*;

/**
 * 
 * @author zhangrb
 * 基础service的实现，所有service类都要继承此类
 * @param <T>
 * @param <ID>
 */
public abstract class BaseServiceImpl<T, ID extends Serializable> implements CommService<T, ID> {
	
	public abstract CommRepository<T, ID> getRepository();
	
	public abstract ID getIdenty(T t);

	public T get(ID id) {
		return getRepository().findOne(id);
	}
	
	public List<T> findAll() {
		return getRepository().findAll();
	}
	
	private Sort makeSort(Map<String, Object>... pm) {
		List<Order> ol = new ArrayList();
		Map[] var3 = pm;
		int var4 = pm.length;

		for(int var5 = 0; var5 < var4; ++var5) {
			Map<String, Object> m = var3[var5];
			Iterator var7 = m.entrySet().iterator();

			while(var7.hasNext()) {
				Map.Entry<String, Object> order = (Map.Entry)var7.next();
				if(!StringUtils.isEmpty(order.getKey()) && ((String)order.getKey()).startsWith("orderby_")) {
					String col = ((String)order.getKey()).replaceFirst("orderby_", "");
					Order o = new Order(Direction.fromString(order.getValue().toString()), col);
					ol.add(o);
				}
			}
		}

		if(ol.isEmpty()) {
			return null;
		} else {
			return new Sort(ol);
		}
	}

	private Specification<T> makeCluase(Map<String, Object>... pm) {
		Specifications<T> ss = null;
		for (Map<String, Object> m : pm) {
			Specification<T> spec = CommSpecification.product(m);
			if(ss == null) {
				ss = Specifications.where(spec);
				continue;
			}
			ss= ss.or(spec);
		}
		return ss;
	}
	
	public List<T> find(Map<String, Object>... pm) {
		Sort sort = makeSort(pm);
		Specification<T> spec = makeCluase(pm);
		return getRepository().findAll(spec, sort);
	}

	public Page<T> findPage(Map<String, Object>... pm) {
		Sort sort = makeSort(pm);
		int page = getPage(pm);
		int rows = getRows(pm);
		Pageable p = buildPageRequest(page, rows, sort);
		Specification<T> spec = makeCluase(pm);
		return getRepository().findAll(spec, p);
	}
	
	private int getPage(Map<String, Object>... pm) {
		for (Map<String, Object> map : pm) {
			for (Map.Entry<String, Object> p : map.entrySet()) {
				if(Constants.PAGE.equals(p.getKey())) {
					String val = p.getValue()==null?null:p.getValue().toString();
					return StringUtils.isEmpty(val) ? 0 : Integer.parseInt(val);
				}
			}
		}
		return 0;
	}
	
	private int getRows(Map<String, Object>... pm) {
		for (Map<String, Object> map : pm) {
			for (Map.Entry<String, Object> p : map.entrySet()) {
				if(Constants.ROWS.equals(p.getKey())) {
					String val = p.getValue()==null?null:p.getValue().toString();
					return StringUtils.isEmpty(val) ? 0 : Integer.parseInt(val);
				}
			}
		}
		return 10;
	}
	
	//构建PageRequest
    private PageRequest buildPageRequest(int page, int rows, Sort s) {
        return new PageRequest(page, rows, s);
    }

	public ID save(T t) {
    	t = getRepository().save(t);
		return getIdenty(t);
	}

	public boolean save(Collection<T> c) {
		getRepository().save(c);
		return true;
	}

	public boolean delete(ID id) {
    	getRepository().delete(id);
		return true;
	}

	public boolean delete(List<ID> l) {
    	for (ID id : l) {
    		delete(id);
		}
		return true;
	}

    @SuppressWarnings("unchecked")
	public boolean delete(Map<String, Object> pm) {
		List<T> l = find(pm);
		getRepository().delete(l);
		return true;
	}

	public long cnt(Map<String, Object>... pm) {
		Specification<T> spec = makeCluase(pm);
		try {
			
		}catch (Exception e) {
			e.printStackTrace();
		}
		return getRepository().count(spec);
	}

		
}
